Skip to content

fix(tui): Fix duplicate tool execution messages in ACP#88

Merged
CSRessel merged 4 commits into
devfrom
claude/fix-duplicate-acp-messages-01VSpy6a82EPYFqVoKu8Wws3
Dec 9, 2025
Merged

fix(tui): Fix duplicate tool execution messages in ACP#88
CSRessel merged 4 commits into
devfrom
claude/fix-duplicate-acp-messages-01VSpy6a82EPYFqVoKu8Wws3

Conversation

@CSRessel
Copy link
Copy Markdown
Collaborator

@CSRessel CSRessel commented Dec 9, 2025

When agent text streams during an ACP tool call execution, the incomplete ExecCell was being flushed to history. When the tool call completed, a new ExecCell was created, resulting in duplicate entries showing both "Running" and "Ran" states for the same command.

This fix tracks incomplete ExecCells that get flushed during streaming in a pending map keyed by call_id. When ExecCommandEnd arrives, the pending cell is retrieved and completed instead of creating a new one.

Changes:

  • Add pending_exec_cells field to ChatWidget to track incomplete cells
  • Modify flush_active_cell to save incomplete ExecCells to pending map
  • Modify handle_exec_end_now to check pending map before creating new
  • Add pending_call_ids method to ExecCell for tracking
  • Add cleanup of pending cells in on_task_complete
  • Add E2E test with interleaved text/tool call events to verify fix

claude and others added 4 commits December 9, 2025 20:19
When agent text streams during an ACP tool call execution, the
incomplete ExecCell was being flushed to history. When the tool call
completed, a new ExecCell was created, resulting in duplicate entries
showing both "Running" and "Ran" states for the same command.

This fix tracks incomplete ExecCells that get flushed during streaming
in a pending map keyed by call_id. When ExecCommandEnd arrives, the
pending cell is retrieved and completed instead of creating a new one.

Changes:
- Add `pending_exec_cells` field to ChatWidget to track incomplete cells
- Modify `flush_active_cell` to save incomplete ExecCells to pending map
- Modify `handle_exec_end_now` to check pending map before creating new
- Add `pending_call_ids` method to ExecCell for tracking
- Add cleanup of pending cells in `on_task_complete`
- Add E2E test with interleaved text/tool call events to verify fix
Move the pending_exec_cells HashMap from ChatWidget into a dedicated
PendingExecCellTracker struct in its own module. This encapsulates the
pending cell tracking logic with typed methods (save_pending, retrieve,
drain_failed), making the code more maintainable and resilient to
upstream TUI changes.
🤖 Generated with [Nori](https://nori.ai)

Co-Authored-By: Nori <contact@tilework.tech>
@CSRessel CSRessel merged commit c6c608e into dev Dec 9, 2025
1 of 3 checks passed
@CSRessel CSRessel deleted the claude/fix-duplicate-acp-messages-01VSpy6a82EPYFqVoKu8Wws3 branch December 9, 2025 22:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants